package com.schoolcloud.gateway.filters;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.nacos.common.utils.StringUtils;
import com.schoolcloud.gateway.config.FroUserStpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;

import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Configuration
@Slf4j
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    private static final String TOKEN_HEADER = "token";
    private static final String USER_TYPE_HEADER = "user-type";
    private static final String USER_ID_HEADER = "user-id";
    private static final String IS_ADMIN_HEADER = "is-admin";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst(TOKEN_HEADER);
        String userType = headers.getFirst(USER_TYPE_HEADER);
        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userType)) {
            return chain.filter(exchange);
        }
        UserInfo userInfo = resolveUserInfo(token, userType);
        // 4. 构建新请求时避免重复创建变量
        ServerWebExchange mutatedExchange = exchange.mutate().request(builder ->
                builder.header(USER_ID_HEADER, userInfo.userId())
                        .header(USER_TYPE_HEADER, userType)
                        .header(IS_ADMIN_HEADER, String.valueOf(userInfo.isAdmin()))
        ).build();
        log.debug("用户认证处理完成 - ID: {}, Type: {}, Admin: {}",
                userInfo.userId(), userType, userInfo.isAdmin());
        return chain.filter(mutatedExchange);
    }

    private UserInfo resolveUserInfo(String token, String userType) {
        String userId = null;
        boolean isAdmin = false;
        try {
            if (FroUserStpUtil.getLoginType().equals(userType)) {
                userId = FroUserStpUtil.getLoginIdAsString();
            } else {
                userId = StpUtil.getLoginIdAsString();
                isAdmin = StpUtil.hasRole("admin");
            }
        } catch (Exception e) {
            log.error("用户信息解析失败 | Token: {}, Type: {} | 错误: {}",
                    token, userType, e.getMessage(), e);
        }
        return new UserInfo(
                StringUtils.defaultIfEmpty(userId, "unknown"),
                isAdmin
        );
    }

    @Override
    public int getOrder() {
        return -100;
    }

    // 内部记录类封装用户信息
    private record UserInfo(String userId, boolean isAdmin) {}
}
